/**
 * Copyright (c) 2008, George Taylor
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification, are permitted 
 * provided that the following conditions are met:
 * 
 *   * Redistributions of source code must retain the above copyright notice, this list of 
 *     conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright notice, this list of 
 *     conditions and the following disclaimer in the documentation and/or other materials 
 *     provided with the distribution.
 *   * Neither the name of the copyright holder's organization nor the names of its contributors 
 *     may be used to endorse or promote products derived from this software without specific 
 *     prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package uk.co.taylorconsulting.annoweb.web.builder.data;

import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashMap;

import uk.co.taylorconsulting.annoweb.annotation.exception.CatchException;
import uk.co.taylorconsulting.annoweb.annotation.form.validation.Validator;
import uk.co.taylorconsulting.annoweb.annotation.security.SecurityHandler;
import uk.co.taylorconsulting.annoweb.annotation.security.SecurityProcessor;
import uk.co.taylorconsulting.annoweb.annotation.web.GlobalDefaultForward;
import uk.co.taylorconsulting.annoweb.annotation.web.GlobalForward;
import uk.co.taylorconsulting.annoweb.annotation.web.QuickLink;

public class Globals {
	private HashMap<Class<? extends Throwable>, Method>                          exceptionHandlers = new HashMap<Class<? extends Throwable>, Method>();
	public HashMap<String, FormData>                                             forms             = new HashMap<String, FormData>();
	private HashMap<String, HashMap<String, Class<? extends SecurityProcessor>>> security          = new HashMap<String, HashMap<String, Class<? extends SecurityProcessor>>>();
	private GlobalDefaultForward                                                 defaultForward;
	private HashMap<String, GlobalForward>                                       forwards          = new HashMap<String, GlobalForward>();
	private HashMap<String, Method>                                              validators        = new HashMap<String, Method>();
	private HashMap<Method, ActionHolder>                                        allActions        = new HashMap<Method, ActionHolder>();
	private ActionHolder                                                         login;
	private ActionHolder                                                         notAuthed;
	private HashMap<String, ActionHolder>                                        quickLinks        = new HashMap<String, ActionHolder>();
	
	public ActionHolder getLogin() {
		return login;
	}
	
	public void setLogin(ActionHolder login) {
		if (this.login == null) {
			this.login = login;
		}
	}
	
	public ActionHolder getNotAuthed() {
		return notAuthed;
	}
	
	public void setNotAuthed(ActionHolder notAuthed) {
		if (this.notAuthed == null) {
			this.notAuthed = notAuthed;
		}
	}
	
	public void addAction(Method m, ActionHolder ah) {
		allActions.put(m, ah);
	}
	
	public ActionHolder getAction(Method m) {
		return allActions.get(m);
	}
	
	public void addExceptionHandler(Method method, CatchException exceptionHandler) {
		if (!exceptionHandlers.containsKey(exceptionHandler.value())) {
			exceptionHandlers.put(exceptionHandler.value(), method);
		}
	}
	
	public Method getExceptionHandler(Class<? extends Throwable> exception) {
		if (exceptionHandlers.containsKey(exception)) {
			return exceptionHandlers.get(exception);
		}
		return exceptionHandlers.get(Throwable.class);
	}
	
	public void addForm(Class<?> clazz) {
		if (!forms.containsKey(clazz.getCanonicalName())) {
			forms.put(clazz.getCanonicalName(), new FormData(clazz));
		}
	}
	
	public FormData getForm(String name) {
		return forms.get(name);
	}
	
	public Collection<FormData> getForms() {
		return forms.values();
	}
	
	public void addSecurityHandler(SecurityHandler a, Class<? extends SecurityProcessor> thisClass) {
		HashMap<String, Class<? extends SecurityProcessor>> realm = security.get(a.realm());
		if (realm == null) {
			realm = new HashMap<String, Class<? extends SecurityProcessor>>();
			security.put(a.realm(), realm);
		}
		if (!realm.containsKey(a.context())) {
			realm.put(a.context(), thisClass);
		}
	}
	
	public void setDefaultForward(GlobalDefaultForward defaultForward) {
		this.defaultForward = defaultForward;
	}
	
	public void addForward(GlobalForward gf) {
		if (!forwards.containsKey(gf.name())) {
			forwards.put(gf.name(), gf);
		}
	}
	
	public GlobalForward getForward(String name) {
		return forwards.get(name);
	}
	
	public Collection<GlobalForward> getForwards() {
		return forwards.values();
	}
	
	public void addValidator(Validator a, Method m) {
		validators.put(a.value(), m);
	}
	
	public GlobalDefaultForward getDefaultForward() {
		return defaultForward;
	}
	
	public HashMap<Class<? extends Throwable>, Method> getExceptionHandlers() {
		return exceptionHandlers;
	}
	
	public HashMap<String, HashMap<String, Class<? extends SecurityProcessor>>> getSecurity() {
		return security;
	}
	
	public void addQuickLink(ActionHolder ah, QuickLink annotation) {
		if (!quickLinks.containsKey(annotation.link())) {
			ah.setQuickLinks(annotation);
			quickLinks.put(annotation.link(), ah);
		}
	}
	
	public HashMap<String, ActionHolder> getQuickLinks() {
		return quickLinks;
	}
}
